﻿using KzwgRoomTester;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;


public class TCPConnection : IConnection
{

    private Socket mSocket = null;
    private ByteBuffer mRecvBuffer = ByteBuffer.Allocate(1024 * 32);

    public bool IsConnected { get { return mSocket != null && mSocket.Connected; } }
    public bool WriteDelay { get; set; }


    public TCPConnection()
    {

    }

    public void Connect(string host, int port)
    {
        var endpoint = IPAddress.Parse(host);
        mSocket = new Socket(endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        mSocket.Connect(endpoint, port);
        mRecvBuffer.Clear();

        //mSocket.BeginConnect(host, port, a =>
        //{
        //    var socket = a.AsyncState as Socket;
        //    if (socket != mSocket)
        //    {
        //        if (socket != null && socket.Connected) socket.Disconnect(false);
        //        return;
        //    }

        //    try { socket.EndConnect(a); }
        //    catch (Exception e)
        //    {
        //        Logger.LogException("Exception occured while connecting to server tcp://{0}:{1}; Exception: {2}", host, port, e);
        //    }

        //    if (socket.Connected)
        //    {
        //        Logger.LogInfo("Connected to server tcp://{0}:{1}!", host, port);
        //    }
        //    else
        //    {
        //        Logger.LogError("Connect to server tcp://{0}:{1} failed!", host, port);

        //    }

        //}, mSocket);

    }



    //public async Task<int> RecvInBuffer()
    public int RecvInBuffer()
    {

        if (mSocket == null)
            return -1;

        if (!mSocket.Poll(0, SelectMode.SelectRead))
        {
            return 0;
        }

        var rn = mSocket.Receive(mRecvBuffer.RawBuffer, mRecvBuffer.WriterIndex, mRecvBuffer.WritableBytes, SocketFlags.None);
        //var result = mSocket.BeginReceive(mRecvBuffer.RawBuffer, mRecvBuffer.WriterIndex, mRecvBuffer.WritableBytes, SocketFlags.None, null, null);
        //rn = await Task.Factory.FromAsync(mSocket.BeginReceive, recevie,  mRecvBuffer.RawBuffer, mRecvBuffer.WriterIndex, mRecvBuffer.WritableBytes, SocketFlags.None, mSocket);
        if (rn <= 0)
        {
            return rn;
        }
        mRecvBuffer.WriterIndex += rn;
        return rn;

    }
   

    public int Send(byte[] data, int index, int length)
    {
        return mSocket.Send(data, 0, data.Length, SocketFlags.None);
    }


    public void Close()
    {
        if (mSocket != null)
        {
            mSocket.Close();
            mSocket = null;
            mRecvBuffer.Clear();
        }
    }


    public int GetRecvLen()
    {
        return mRecvBuffer.ReadableBytes;
    }

    public int RecvData(byte[] data, int index, int length)
    {
        if (mRecvBuffer.ReadableBytes > 0)
        {
            var recvBytes = Math.Min(mRecvBuffer.ReadableBytes, length);
            Buffer.BlockCopy(mRecvBuffer.RawBuffer, mRecvBuffer.ReaderIndex, data, index, recvBytes);
            mRecvBuffer.ReaderIndex += recvBytes;
            // 重置读写指针
            if (mRecvBuffer.ReaderIndex == mRecvBuffer.WriterIndex)
            {
                mRecvBuffer.Clear();
            }
            else
            {
                mRecvBuffer.TrimReadedBytes();
            }
            return recvBytes;
        }
        return 0;
    }
}

